React Suspense ๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๋ง์คํฐํ์ธ์. ๊ธ๋ก๋ฒ ๋ชจ๋ฒ ์ฌ๋ก, ํด๋ฐฑ UI, ์ ์ธ๊ณ์ ์ผ๋ก ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๊ฒฌ๊ณ ํ ์ ๋ต์ ๋ฐฐ์ฐ์ญ์์ค.
๊ฒฌ๊ณ ํ React Suspense ์ค๋ฅ ๋ณต๊ตฌ: ๋ก๋ฉ ์คํจ ์ฒ๋ฆฌ๋ฅผ ์ํ ๊ธ๋ก๋ฒ ๊ฐ์ด๋
ํ๋ ์น ๊ฐ๋ฐ์ ๋์ ์ธ ํ๊ฒฝ์์, ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋๋ ๊ฒ์ ๋น๋๊ธฐ ์์ ์ ์ผ๋ง๋ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋๋์ ๋ฌ๋ ค ์์ต๋๋ค. ํ์ ์ ์ธ ๊ธฐ๋ฅ์ธ React Suspense๋ ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ํ์ ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ๋น ๋ฅด๊ณ ํตํฉ์ ์ผ๋ก ๋๋ผ๊ฒ ๋ง๋ค๊ฒ ๋ค๊ณ ์ฝ์ํ์ต๋๋ค. ์ด๋ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ ์ฝ๋์ ๊ฐ์ "๋ฌด์ธ๊ฐ"๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ฒ ํ๋ฉฐ, ๊ทธ๋์ ํด๋ฐฑ UI๋ฅผ ํ์ํฉ๋๋ค. ์ด ์ ์ธ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ ํต์ ์ธ ๋ช ๋ นํ ๋ก๋ฉ ํ์๊ธฐ๋ณด๋ค ํจ์ฌ ํฅ์๋์ด ๋ ์์ฐ์ค๋ฝ๊ณ ์ ๋์ ์ธ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ ํ์นญ์ ์ฌ์ ์ ์ํ์น ์์ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋คํธ์ํฌ ์ค๋จ, ์๋ฒ ์ธก ์ค๋ฅ, ์ ํจํ์ง ์์ ๋ฐ์ดํฐ, ์ฌ์ง์ด ์ฌ์ฉ์ ๊ถํ ๋ฌธ์ ๊น์ง ์ํํ ๋ฐ์ดํฐ ํ์นญ์ ์ข์ ์ค๋ฌ์ด ๋ก๋ฉ ์คํจ๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค. Suspense๋ ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํ์ง๋ง, ์ด๋ฌํ ๋น๋๊ธฐ ์์ ์ ์คํจ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๋ณธ์ง์ ์ผ๋ก ์ค๊ณ๋์ง ์์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ React Suspense์ Error Boundaries์ ๊ฐ๋ ฅํ ์๋์ง๊ฐ ๋ฐํ๋์ด, ๊ฒฌ๊ณ ํ ์ค๋ฅ ๋ณต๊ตฌ ์ ๋ต์ ์ด์์ ํ์ฑํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ค์๊ฒ ํฌ๊ด์ ์ธ ์ค๋ฅ ๋ณต๊ตฌ์ ์ค์์ฑ์ ์๋ฌด๋ฆฌ ๊ฐ์กฐํด๋ ์ง๋์น์ง ์์ต๋๋ค. ๋ค์ํ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ์ฌ์ฉ์๋ค์ ๋ค์ํ ๋คํธ์ํฌ ํ๊ฒฝ, ๊ธฐ๊ธฐ ์ฑ๋ฅ, ๋ฐ์ดํฐ ์ ๊ทผ ์ ํ ์์์ ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์กดํฉ๋๋ค. ํ ์ง์ญ์ ๋๋ฆฌ๊ฑฐ๋ ๋ถ์์ ํ ์ธํฐ๋ท ์ฐ๊ฒฐ, ๋ค๋ฅธ ์ง์ญ์ ์ผ์์ ์ธ API ์ค๋จ, ๋๋ ๋ฐ์ดํฐ ํ์ ๋นํธํ์ฑ ๋ฑ ์ด ๋ชจ๋ ๊ฒ์ด ๋ก๋ฉ ์คํจ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ ์ ์๋ ์ค๋ฅ ์ฒ๋ฆฌ ์ ๋ต์ด ์๋ค๋ฉด, ์ด๋ฌํ ์๋๋ฆฌ์ค๋ ๊นจ์ง UI, ํผ๋์ค๋ฌ์ด ๋ฉ์์ง, ์ฌ์ง์ด ์์ ํ ์๋ตํ์ง ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ํ์ฌ ์ฌ์ฉ์ ์ ๋ขฐ๋ฅผ ์นจ์ํ๊ณ ๊ธ๋ก๋ฒ ์ฐธ์ฌ์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋๋ React Suspense๋ฅผ ์ด์ฉํ ์ค๋ฅ ๋ณต๊ตฌ ๋ง์คํฐ๋ง์ ๋ํด ๊น์ด ํ๊ตฌํ์ฌ, ์ฌ๋ฌ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์ ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ด๋ฉฐ ์ ์ธ๊ณ์ ์ผ๋ก ๊ฒฌ๊ณ ํ๊ฒ ์ ์ง๋๋๋ก ๋ณด์ฅํ ๊ฒ์ ๋๋ค.
React Suspense ๋ฐ ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ๋ฆ ์ดํดํ๊ธฐ
์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ ์, ํนํ ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ์นญ ๋งฅ๋ฝ์์ React Suspense๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง ๊ฐ๋ตํ๊ฒ ๋ค์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. Suspense๋ ์ปดํฌ๋ํธ๊ฐ "๋ฌด์ธ๊ฐ"๋ฅผ ์ ์ธ์ ์ผ๋ก "๊ธฐ๋ค๋ฆฌ๊ฒ" ํ๊ณ , ๊ทธ "๋ฌด์ธ๊ฐ"๊ฐ ์ค๋น๋ ๋๊น์ง ํด๋ฐฑ UI๋ฅผ ๋ ๋๋งํ๋ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ์ ํต์ ์ผ๋ก๋ ๊ฐ ์ปดํฌ๋ํธ ๋ด์์ `isLoading` ๋ถ๋ฆฌ์ธ๊ณผ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฌ์ฉํ์ฌ ๋ช ๋ นํ์ผ๋ก ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํ์ต๋๋ค. Suspense๋ ์ด ํจ๋ฌ๋ค์์ ๋ค์ง์ด, ํ๋ผ๋ฏธ์ค๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง์ "์ค๋จ"ํ๋๋ก ํ์ฉํฉ๋๋ค.
React Suspense๋ ๋ฆฌ์์ค์ ๊ตฌ์ ๋ฐ์ง ์์ต๋๋ค. ์ฝ๋ ์คํ๋ฆฌํ ์ ์ํ `React.lazy`์ ํํ ์ฐ๊ด๋์ง๋ง, ๊ทธ ์ง์ ํ ํ์ ๋ฐ์ดํฐ ํ์นญ์ ํฌํจํ์ฌ ํ๋ผ๋ฏธ์ค๋ก ํํ๋ ์ ์๋ ๋ชจ๋ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์์ต๋๋ค. Relay์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ํ์นญ ์๋ฃจ์ ์ ๋ฐ์ดํฐ๊ฐ ์์ง ์ค๋น๋์ง ์์์ ๋ ํ๋ผ๋ฏธ์ค๋ฅผ ๋์ง์ผ๋ก์จ Suspense์ ํตํฉ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด React๋ ์ด ๋์ ธ์ง ํ๋ผ๋ฏธ์ค๋ฅผ catchํ์ฌ ๊ฐ์ฅ ๊ฐ๊น์ด `<Suspense>` ๊ฒฝ๊ณ๋ฅผ ์ฐพ๊ณ , ํ๋ผ๋ฏธ์ค๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ํด๋น `fallback` prop์ ๋ ๋๋งํฉ๋๋ค. ํด๊ฒฐ๋๋ฉด React๋ ์ค๋จ๋์๋ ์ปดํฌ๋ํธ ๋ ๋๋ง์ ๋ค์ ์๋ํฉ๋๋ค.
์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๊ณ ๋ คํด ๋ด ์๋ค:
์ด "ํจ์ํ ์ปดํฌ๋ํธ" ์์๋ ๋ฐ์ดํฐ ๋ฆฌ์์ค๊ฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋ ์ ์๋์ง ๋ณด์ฌ์ค๋๋ค:
const userData = userResource.read();
`userResource.read()`๊ฐ ํธ์ถ๋ ๋, ๋ฐ์ดํฐ๊ฐ ์์ง ์ค๋น๋์ง ์์๋ค๋ฉด ํ๋ผ๋ฏธ์ค๋ฅผ ๋์ง๋๋ค. React์ Suspense ๋ฉ์ปค๋์ฆ์ ์ด๋ฅผ ๊ฐ๋ก์ฑ์, ํ๋ผ๋ฏธ์ค๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ํ๋ผ๋ฏธ์ค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ํด๊ฒฐ๋๋ฉด ๋ฐ์ดํฐ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๊ณ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ํ๋ผ๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ๋๋ฉด Suspense ์์ฒด๋ ์ด ๊ฑฐ๋ถ๋ฅผ ํ์ํ ์ค๋ฅ ์ํ๋ก ๋ณธ์ง์ ์ผ๋ก ํฌ์ฐฉํ์ง ์์ต๋๋ค. ๋จ์ํ ๊ฑฐ๋ถ๋ ํ๋ผ๋ฏธ์ค๋ฅผ ๋ค์ ๋์ง๋ฉฐ, ์ด๋ React ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ๋ฒ๋ธ๋ง๋ฉ๋๋ค.
์ด๋ฌํ ๊ตฌ๋ถ์ ๋งค์ฐ ์ค์ํฉ๋๋ค: Suspense๋ ํ๋ผ๋ฏธ์ค์ ๋๊ธฐ ์ค์ธ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด์ง, ๊ฑฐ๋ถ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์๋๋๋ค. ์ด๋ ์ํํ ๋ก๋ฉ ๊ฒฝํ์ ์ ๊ณตํ์ง๋ง, ํ๋ผ๋ฏธ์ค๊ฐ ๊ฒฐ๊ตญ ํด๊ฒฐ๋ ๊ฒ์ ๊ธฐ๋ํฉ๋๋ค. ํ๋ผ๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ๋ ๊ฒฝ์ฐ, Suspense ๊ฒฝ๊ณ ๋ด์์ ์ฒ๋ฆฌ๋์ง ์์ ๊ฑฐ๋ถ๊ฐ ๋์ด ๋ค๋ฅธ ๋ฉ์ปค๋์ฆ์ ์ํด ์กํ์ง ์์ผ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ถฉ๋ ๋๋ ๋น ํ๋ฉด์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด ๊ฒฉ์ฐจ๋ ํนํ ๋คํธ์ํฌ ์์ ์ฑ๊ณผ API ์์ ์ฑ์ด ํฌ๊ฒ ๋ฌ๋ผ์ง ์ ์๋ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ํ๊ณ ํ๋ ฅ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํด Suspense๋ฅผ ์ ์ฉ ์ค๋ฅ ์ฒ๋ฆฌ ์ ๋ต, ํนํ Error Boundaries์ ๊ฒฐํฉํด์ผ ํ ํ์์ฑ์ ๊ฐ์กฐํฉ๋๋ค.
ํ๋ ์น ์ฑ์ ๋น๋๊ธฐ์ ํน์ฑ
ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณธ์ง์ ์ผ๋ก ๋น๋๊ธฐ์ ์ ๋๋ค. ๋ฐฑ์๋ ์๋ฒ, ์๋ํํฐ API์ ํต์ ํ๋ฉฐ, ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ์ต์ ํํ๊ธฐ ์ํด ์ฝ๋ ๋ถํ ์ ์ํ ๋์ ์ํฌํธ์ ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด๋ฌํ ๊ฐ ์ํธ์์ฉ์ ๋คํธ์ํฌ ์์ฒญ ๋๋ ์ง์ฐ๋ ์์ ์ ํฌํจํ๋ฉฐ, ์ฑ๊ณตํ๊ฑฐ๋ ์คํจํ ์ ์์ต๋๋ค. ์ ์ญ์ ๋งฅ๋ฝ์์, ์ด๋ฌํ ์์ ์ ๋ค์๊ณผ ๊ฐ์ ์๋ง์ ์ธ๋ถ ์์ธ์ ์ํฅ์ ๋ฐ์ต๋๋ค:
- ๋คํธ์ํฌ ์ง์ฐ: ์ฌ๋ฌ ๋๋ฅ์ ์ฌ์ฉ์๋ค์ ๋ค์ํ ๋คํธ์ํฌ ์๋๋ฅผ ๊ฒฝํํ ๊ฒ์ ๋๋ค. ํ ์ง์ญ์์ ๋ฐ๋ฆฌ์ด๊ฐ ๊ฑธ๋ฆฌ๋ ์์ฒญ์ ๋ค๋ฅธ ์ง์ญ์์ ์ด ๋จ์๋ก ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
- ์ฐ๊ฒฐ ๋ฌธ์ : ๋ชจ๋ฐ์ผ ์ฌ์ฉ์, ์๊ฒฉ ์ง์ญ ์ฌ์ฉ์ ๋๋ ๋ถ์์ ํ Wi-Fi ์ฐ๊ฒฐ ์ฌ์ฉ์๋ค์ ์ฐ๊ฒฐ ๋๊น ๋๋ ๊ฐํ์ ์ธ ์๋น์ค์ ์์ฃผ ์ง๋ฉดํฉ๋๋ค.
- API ์์ ์ฑ: ๋ฐฑ์๋ ์๋น์ค๋ ๋ค์ดํ์์ ๊ฒช๊ฑฐ๋ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๊ฑฐ๋ ์์์น ๋ชปํ ์ค๋ฅ ์ฝ๋๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค. ์๋ํํฐ API๋ ์๋ ์ ํ ๋๋ ๊ฐ์์ค๋ฌ์ด ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ๊ฐ์ฉ์ฑ: ํ์ํ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋, ์์๋์๊ฑฐ๋, ๋๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ๋ ๋ฐ ํ์ํ ๊ถํ์ด ์์ ์ ์์ต๋๋ค.
๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ์์ผ๋ฉด ์ด๋ฌํ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค ์ค ์ด๋ ํ๋๋ผ๋ ์ฌ์ฉ์ ๊ฒฝํ ์ ํ๋ฅผ ์ด๋ํ๊ฑฐ๋, ๋ ๋์๊ฒ๋ ์์ ํ ์ฌ์ฉํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. Suspense๋ '๋๊ธฐ' ๋ถ๋ถ์ ๋ํ ์ฐ์ํ ์๋ฃจ์ ์ ์ ๊ณตํ์ง๋ง, '๋ฌด์์ธ๊ฐ ์๋ชป๋ ๊ฒฝ์ฐ'๋ฅผ ์ํด์๋ ๋ค๋ฅธ, ๋๊ฐ์ด ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ํ์ํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ์ ์ค์ํ ์ญํ
React์ Error Boundaries๋ ํฌ๊ด์ ์ธ ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ Suspense์ ํ์์ ์ธ ํํธ๋์ ๋๋ค. React 16์์ ๋์ ๋ Error Boundaries๋ ์์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด์ JavaScript ์ค๋ฅ๋ฅผ ์ด๋์๋ ํฌ์ฐฉํ๊ณ , ํด๋น ์ค๋ฅ๋ฅผ ๋ก๊น ํ๋ฉฐ, ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ถฉ๋ํ๋ ๋์ ํด๋ฐฑ UI๋ฅผ ํ์ํ๋ React ์ปดํฌ๋ํธ์ ๋๋ค. ์ด๋ Suspense๊ฐ ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์๊ณผ ์ ์ฌํ๊ฒ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ์ ์ธ์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค.
Error Boundary๋ ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋์ธ `static getDerivedStateFromError()` ๋๋ `componentDidCatch()` ์ค ํ๋(๋๋ ๋ ๋ค)๋ฅผ ๊ตฌํํ๋ ํด๋์ค ์ปดํฌ๋ํธ์ ๋๋ค.
- `static getDerivedStateFromError(error)`: ์ด ๋ฉ์๋๋ ์์ ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ๋์ ธ์ง ์ค๋ฅ๋ฅผ ๋ฐ์ผ๋ฉฐ, ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ๊ฐ์ ๋ฐํํ์ฌ ๊ฒฝ๊ณ๊ฐ ํด๋ฐฑ UI๋ฅผ ๋ ๋๋งํ ์ ์๋๋ก ํด์ผ ํฉ๋๋ค. ์ด ๋ฉ์๋๋ ์ค๋ฅ UI๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- `componentDidCatch(error, errorInfo)`: ์ด ๋ฉ์๋๋ ์์ ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ์ ํจ๊ป ์ด๋ค ์ปดํฌ๋ํธ๊ฐ ์ค๋ฅ๋ฅผ ๋์ก๋์ง์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด ๊ฐ์ฒด๋ฅผ ๋ฐ์ต๋๋ค. ์ด ๋ฉ์๋๋ ์ผ๋ฐ์ ์ผ๋ก ๋ถ์ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๋ก๊น ํ๊ฑฐ๋ ์ ์ญ ์ค๋ฅ ์ถ์ ์์คํ ์ ๋ณด๊ณ ํ๋ ๋ฑ ๋ถ์์ฉ์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
๋ค์์ Error Boundary์ ๊ธฐ๋ณธ ๊ตฌํ์ ๋๋ค:
์ด๊ฒ์ "๊ฐ๋จํ Error Boundary ์ปดํฌ๋ํธ"์ ์์์ ๋๋ค:
class ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { hasError: false, error: null, errorInfo: null };\n }\n\n static getDerivedStateFromError(error) {\n // Update state so the next render will show the fallback UI.\n return { hasError: true, error };\n }\n\n componentDidCatch(error, errorInfo) {\n // You can also log the error to an error reporting service\n console.error("Uncaught error:", error, errorInfo);\n this.setState({ errorInfo });\n // Example: send error to a global logging service\n // globalErrorLogger.log(error, errorInfo, { componentStack: errorInfo.componentStack });\n }\n\n render() {\n if (this.state.hasError) {\n // You can render any custom fallback UI\n return (\n <div style={{ padding: '20px', border: '1px solid red', backgroundColor: '#ffe6e6' }}>\n <h2>๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.</h2>\n <p>๋ถํธ์ ๋๋ ค ์ฃ์กํฉ๋๋ค. ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ๊ฑฐ๋ ๋ฌธ์ ๊ฐ ์ง์๋๋ฉด ๊ณ ๊ฐ ์ง์ํ์ ๋ฌธ์ํ์ญ์์ค.</p>\n {this.props.showDetails && this.state.error && (\n <details style={{ whiteSpace: 'pre-wrap' }}>\n <summary>์ค๋ฅ ์ธ๋ถ ์ ๋ณด</summary>\n <p>\n <b>์ค๋ฅ:</b> {this.state.error.toString()}\n </p>\n <p>\n <b>์ปดํฌ๋ํธ ์คํ:</b> {this.state.errorInfo && this.state.errorInfo.componentStack}\n </p>\n </details>\n )}\n {this.props.onRetry && (\n <button onClick={this.props.onRetry} style={{ marginTop: '10px' }}>์ฌ์๋</button>\n )}\n </div>\n );\n }\n return this.props.children;\n }\n}\n
Error Boundaries๋ Suspense๋ฅผ ์ด๋ป๊ฒ ๋ณด์ํ ๊น์? Suspense๊ฐ ํ์ฑํ๋ ๋ฐ์ดํฐ ํ์ฒ๊ฐ ๋์ง ํ๋ผ๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ๋ ๋ (๋ฐ์ดํฐ ํ์นญ์ด ์คํจํ์์ ์๋ฏธ), ์ด ๊ฑฐ๋ถ๋ React์ ์ํด ์ค๋ฅ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ด ์ค๋ฅ๋ ๊ฐ์ฅ ๊ฐ๊น์ด Error Boundary์ ์ํด ํฌ์ฐฉ๋ ๋๊น์ง ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ๋ฒ๋ธ๋ง๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด Error Boundary๋ ์์ ๋ ๋๋ง์์ ํด๋ฐฑ UI ๋ ๋๋ง์ผ๋ก ์ ํํ์ฌ, ์ถฉ๋ ๋์ ์ฐ์ํ ์ฑ๋ฅ ์ ํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด๋ฌํ ํํธ๋์ญ์ ๋งค์ฐ ์ค์ํฉ๋๋ค: Suspense๋ ์ ์ธ์ ์ธ ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ, ๋ฐ์ดํฐ๊ฐ ์ค๋น๋ ๋๊น์ง ํด๋ฐฑ์ ํ์ํฉ๋๋ค. Error Boundaries๋ ์ ์ธ์ ์ธ ์ค๋ฅ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ, ๋ฐ์ดํฐ ํ์นญ(๋๋ ๋ค๋ฅธ ์์ )์ด ์คํจํ ๋ ๋ค๋ฅธ ํด๋ฐฑ์ ํ์ํฉ๋๋ค. ์ด๋ค์ ํจ๊ป ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฐฉ์์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์ ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ํฌ๊ด์ ์ธ ์ ๋ต์ ๋ง๋ญ๋๋ค.
๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ํ ๊ตฌ๋ถํ๊ธฐ
Suspense์ Error Boundaries์ ์ต์ํ์ง ์์ ๊ฐ๋ฐ์๋ค์๊ฒ ํํ ํผ๋์ค๋ฌ์ด ์ ์ค ํ๋๋ ์ฌ์ ํ ๋ก๋ฉ ์ค์ธ ์ปดํฌ๋ํธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ๋ณํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ํต์ฌ์ ๊ฐ ๋ฉ์ปค๋์ฆ์ด ๋ฌด์์ ๋ฐ์ํ๋์ง ์ดํดํ๋ ๋ฐ ์์ต๋๋ค:
- Suspense: ๋์ ธ์ง ํ๋ผ๋ฏธ์ค์ ๋ฐ์ํฉ๋๋ค. ์ด๋ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์์ ๋ํ๋ ๋๋ค. ์ด ๋๊ธฐ ๊ธฐ๊ฐ ๋์ ํด๋น ํด๋ฐฑ UI(`<Suspense fallback={<LoadingSpinner />}>`)๊ฐ ํ์๋ฉ๋๋ค.
- Error Boundary: ๋์ ธ์ง ์ค๋ฅ(๋๋ ๊ฑฐ๋ถ๋ ํ๋ผ๋ฏธ์ค)์ ๋ฐ์ํฉ๋๋ค. ์ด๋ ๋ ๋๋ง ๋๋ ๋ฐ์ดํฐ ํ์นญ ์ค์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์์ ๋ํ๋ ๋๋ค. ์ค๋ฅ ๋ฐ์ ์ ํด๋น ํด๋ฐฑ UI(`hasError`๊ฐ true์ผ ๋ `render` ๋ฉ์๋ ๋ด์์ ์ ์๋จ)๊ฐ ํ์๋ฉ๋๋ค.
๋ฐ์ดํฐ ํ์นญ ํ๋ผ๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ๋๋ฉด, ์ค๋ฅ๋ก ์ ํ๋์ด Suspense์ ๋ก๋ฉ ํด๋ฐฑ์ ์ฐํํ๊ณ Error Boundary์ ์ํด ์ง์ ํฌ์ฐฉ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด '๋ก๋ฉ ์ค'๊ณผ '๋ก๋ ์คํจ'์ ๋ํด ๋ช ํํ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์์ผ๋ฉฐ, ํนํ ๊ธ๋ก๋ฒ ๊ท๋ชจ์์ ๋คํธ์ํฌ ์กฐ๊ฑด์ด๋ ๋ฐ์ดํฐ ๊ฐ์ฉ์ฑ์ด ์์ธก ๋ถ๊ฐ๋ฅํ ๋ ์ฌ์ฉ์์๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ์๋ดํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
Suspense ๋ฐ Error Boundaries๋ฅผ ์ด์ฉํ ์ค๋ฅ ๋ณต๊ตฌ ๊ตฌํ
๋ก๋ฉ ์คํจ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด Suspense์ Error Boundaries๋ฅผ ํตํฉํ๋ ์ค์ ์๋๋ฆฌ์ค๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ํต์ฌ ์์น์ Suspense๊ฐ ํ์ฑํ๋ ์ปดํฌ๋ํธ(๋๋ Suspense ๊ฒฝ๊ณ ์์ฒด)๋ฅผ Error Boundary ๋ด๋ถ์ ๋ํํ๋ ๊ฒ์ ๋๋ค.
์๋๋ฆฌ์ค 1: ์ปดํฌ๋ํธ ์์ค ๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ
์ด๊ฒ์ ๊ฐ์ฅ ์ธ๋ถํ๋ ์์ค์ ์ค๋ฅ ์ฒ๋ฆฌ์ ๋๋ค. ํน์ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ ๋ก๋ฉ์ ์คํจํ ๊ฒฝ์ฐ, ํ์ด์ง์ ๋๋จธ์ง ๋ถ๋ถ์ ์ํฅ์ ์ฃผ์ง ์๊ณ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋๋ก ํ๊ณ ์ถ์ ๋ ์ฌ์ฉํฉ๋๋ค.
ํน์ ์ ํ์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ `ProductDetails` ์ปดํฌ๋ํธ๋ฅผ ์์ํด ๋ณด์ธ์. ์ด ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์คํจํ๋ฉด ํด๋น ์น์ ์๋ง ์ค๋ฅ๋ฅผ ํ์ํ๊ณ ์ถ์ ๊ฒ์ ๋๋ค.
๋จผ์ , ๋ฐ์ดํฐ ํ์ฒ๊ฐ Suspense์ ํตํฉ๋๊ณ ์คํจ๋ฅผ ๋ํ๋ผ ์ ์๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ํจํด์ "๋ฆฌ์์ค" ๋ํผ๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ชจ ๋ชฉ์ ์ผ๋ก, ๋ณด๋ฅ ์ํ์ ๋ํด์๋ ํ๋ผ๋ฏธ์ค๋ฅผ ๋์ง๊ณ ์คํจ ์ํ์ ๋ํด์๋ ์ค์ ์ค๋ฅ๋ฅผ ๋์ง์ผ๋ก์จ ์ฑ๊ณต๊ณผ ์คํจ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ๋ ๋จ์ํ๋ `createResource` ์ ํธ๋ฆฌํฐ๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์ด๊ฒ์ "๋ฐ์ดํฐ ํ์นญ์ ์ํ ๊ฐ๋จํ `createResource` ์ ํธ๋ฆฌํฐ"์ ์์์ ๋๋ค:
const createResource = (fetcher) => {\n let status = 'pending';\n let result;\n let suspender = fetcher().then(\n (r) => {\n status = 'success';\n result = r;\n },\n (e) => {\n status = 'error';\n result = e;\n }\n );\n\n return {\n read() {\n if (status === 'pending') {\n throw suspender;\n } else if (status === 'error') {\n throw result; // Throw the actual error\n } else if (status === 'success') {\n return result;\n }\n },\n };\n};\n
์ด์ ์ด๊ฒ์ `ProductDetails` ์ปดํฌ๋ํธ์์ ์ฌ์ฉํด ๋ด ์๋ค:
์ด๊ฒ์ "๋ฐ์ดํฐ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ์ ํ ์ธ๋ถ ์ ๋ณด ์ปดํฌ๋ํธ"์ ์์์ ๋๋ค:
const ProductDetails = ({ productId }) => {\n // Assume 'fetchProduct' is an async function that returns a Promise\n // For demonstration, let's make it fail sometimes\n const productResource = React.useMemo(() => {\n return createResource(() => {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n if (Math.random() > 0.5) { // Simulate 50% chance of failure\n reject(new Error(`Failed to load product ${productId}. Please check network.`));\n } else {\n resolve({\n id: productId,\n name: `Global Product ${productId}`,\n description: `This is a high-quality product from around the world, ID: ${productId}.`,\n price: (100 + productId * 10).toFixed(2)\n });\n }\n }, 1500); // Simulate network delay\n });\n });\n }, [productId]);\n\n const product = productResource.read();\n\n return (\n <div style={{ border: '1px solid #ccc', padding: '15px', borderRadius: '5px', backgroundColor: '#f9f9f9' }}>\n <h3>์ ํ: {product.name}</h3>\n <p>{product.description}</p>\n <p><strong>๊ฐ๊ฒฉ:</strong> ${product.price}</p>\n <em>๋ฐ์ดํฐ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋๋์์ต๋๋ค!</em>\n </div>\n );\n};\n
๋ง์ง๋ง์ผ๋ก, `ProductDetails`๋ฅผ `Suspense` ๊ฒฝ๊ณ ๋ด์ ๋ํํ๊ณ , ๊ทธ ์ ์ฒด ๋ธ๋ก์ `ErrorBoundary` ๋ด์ ๋ํํฉ๋๋ค:
์ด๊ฒ์ "์ปดํฌ๋ํธ ์์ค์์ Suspense์ Error Boundary ํตํฉ"์ ์์์ ๋๋ค:
function App() {\n const [productId, setProductId] = React.useState(1);\n const [retryKey, setRetryKey] = React.useState(0);\n\n const handleRetry = () => {\n // By changing the key, we force the component to remount and re-fetch\n setRetryKey(prevKey => prevKey + 1);\n console.log("Attempting to retry product data fetch.");\n };\n\n return (\n <div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>\n <h1>๊ธ๋ก๋ฒ ์ ํ ๋ทฐ์ด</h1>\n <p>์์ธํ ๋ด์ฉ์ ๋ณด๋ ค๋ฉด ์ ํ์ ์ ํํ์ญ์์ค:</p>\n <div style={{ marginBottom: '20px' }}>\n {[1, 2, 3, 4].map(id => (\n <button\n key={id}\n onClick={() => setProductId(id)}\n style={{ marginRight: '10px', padding: '8px 15px', cursor: 'pointer', backgroundColor: productId === id ? '#007bff' : '#f0f0f0', color: productId === id ? 'white' : 'black', border: 'none', borderRadius: '4px' }}\n >\n ์ ํ {id}\n </button>\n ))}\n </div>\n\n <div style={{ minHeight: '200px', border: '1px solid #eee', padding: '20px', borderRadius: '8px' }}>\n <h2>์ ํ ์ธ๋ถ ์ ๋ณด ์น์
</h2>\n <ErrorBoundary\n key={productId + '-' + retryKey} // Keying the ErrorBoundary helps reset its state on product change or retry\n showDetails={true}\n onRetry={handleRetry}\n >\n <Suspense fallback={<div>ID {productId}์ ๋ํ ์ ํ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ ์ค...</div>}>\n <ProductDetails productId={productId} />\n </Suspense>\n </ErrorBoundary>\n </div>\n\n <p style={{ marginTop: '30px', fontSize: '0.9em', color: '#666' }}>\n <em>์ฐธ๊ณ : ์ ํ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ์์ฐํ๊ธฐ ์ํด 50%์ ์คํจ ํ๋ฅ ์ ๊ฐ์ง๋๋ค.</em>\n </p>\n </div>\n );\n}\n
์ด ์ค์ ์์ `ProductDetails`๊ฐ ํ๋ผ๋ฏธ์ค๋ฅผ ๋์ง๋ฉด (๋ฐ์ดํฐ ๋ก๋ฉ), `Suspense`๊ฐ ์ด๋ฅผ ํฌ์ฐฉํ๊ณ "๋ก๋ฉ ์ค..."์ ํ์ํฉ๋๋ค. `ProductDetails`๊ฐ *์ค๋ฅ*๋ฅผ ๋์ง๋ฉด (๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ), `ErrorBoundary`๊ฐ ์ด๋ฅผ ํฌ์ฐฉํ๊ณ ์ฌ์ฉ์ ์ ์ ์ค๋ฅ UI๋ฅผ ํ์ํฉ๋๋ค. `ErrorBoundary`์ `key` prop์ ์ฌ๊ธฐ์ ์ค์ํฉ๋๋ค: `productId` ๋๋ `retryKey`๊ฐ ๋ณ๊ฒฝ๋๋ฉด, React๋ `ErrorBoundary`์ ๊ทธ ์์๋ค์ ์์ ํ ์๋ก์ด ์ปดํฌ๋ํธ๋ก ์ฒ๋ฆฌํ์ฌ ๋ด๋ถ ์ํ๋ฅผ ์ฌ์ค์ ํ๊ณ ์ฌ์๋ ๊ธฐํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ํจํด์ ์ผ์์ ์ธ ๋คํธ์ํฌ ๋ฌธ์ ๋ก ์ธํด ์ฌ์ฉ์๊ฐ ์คํจํ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ช ์์ ์ผ๋ก ์ฌ์๋ํ๊ณ ์ถ์ด ํ ์ ์๋ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ํนํ ์ ์ฉํฉ๋๋ค.
์๋๋ฆฌ์ค 2: ์ ์ญ/์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด ๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ
๋๋ก๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํฐ ๋ถ๋ถ์ ๊ตฌ๋ํ๋ ์ค์ํ ๋ฐ์ดํฐ ์กฐ๊ฐ์ด ๋ก๋์ ์คํจํ ์ ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ, ๋ ๋์ ๋๋ ์ค๋ฅ ํ์๊ฐ ํ์ํ๊ฑฐ๋, ํ์ ์ต์ ์ ์ ๊ณตํ๊ณ ์ถ์ ์ ์์ต๋๋ค.
์ฌ์ฉ์์ ์ ์ฒด ํ๋กํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ ๋์๋ณด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ฐํด ๋ณด์ธ์. ์ด ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์คํจํ ๊ฒฝ์ฐ, ํ๋ฉด์ ์์ ๋ถ๋ถ์๋ง ์ค๋ฅ๋ฅผ ํ์ํ๋ ๊ฒ์ ๋ถ์ถฉ๋ถํ ์ ์์ต๋๋ค. ๋์ , ๋ค๋ฅธ ์น์ ์ผ๋ก ์ด๋ํ๊ฑฐ๋ ๊ณ ๊ฐ ์ง์ํ์ ๋ฌธ์ํ ์ ์๋ ์ต์ ์ด ์๋ ์ ์ฒด ํ์ด์ง ์ค๋ฅ๋ฅผ ์ํ ์ ์์ต๋๋ค.
์ด ์๋๋ฆฌ์ค์์๋ `ErrorBoundary`๋ฅผ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ๋ ๋์ ๊ณณ์ ๋ฐฐ์นํ์ฌ, ์ ์ฒด ๋ผ์ฐํธ ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฃผ์ ์น์ ์ ๋ํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฌ๋ฌ ์์ ์ปดํฌ๋ํธ ๋๋ ์ค์ํ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์์ ์ ํ๋๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ ์ ์์ต๋๋ค.
์ด๊ฒ์ "์ ํ๋ฆฌ์ผ์ด์ ์์ค ์ค๋ฅ ์ฒ๋ฆฌ"์ ์์์ ๋๋ค:
// Assume GlobalDashboard is a component that loads multiple pieces of data\n// and uses Suspense internally for each, e.g., UserProfile, LatestOrders, AnalyticsWidget\nconst GlobalDashboard = () => {\n return (\n <div>\n <h2>๊ทํ์ ๊ธ๋ก๋ฒ ๋์๋ณด๋</h2>\n <Suspense fallback={<p>์ค์ ๋์๋ณด๋ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ ์ค...</p>}>\n <UserProfile />\n </Suspense>\n <Suspense fallback={<p>์ต์ ์ฃผ๋ฌธ ๋ก๋ ์ค...</p>}>\n <LatestOrders />\n </Suspense>\n <Suspense fallback={<p>๋ถ์ ๋ก๋ ์ค...</p>}>\n <AnalyticsWidget />\n </Suspense>\n </div>\n );\n};\n\nfunction MainApp() {\n const [retryAppKey, setRetryAppKey] = React.useState(0);\n\n const handleAppRetry = () => {\n setRetryAppKey(prevKey => prevKey + 1);\n console.log("Attempting to retry the entire application/dashboard load.");\n // Potentially navigate to a safe page or re-initialize critical data fetches\n };\n\n return (\n <div>\n <nav>... ๊ธ๋ก๋ฒ ํ์ ...</nav>\n <ErrorBoundary key={retryAppKey} showDetails={false} onRetry={handleAppRetry}>\n <GlobalDashboard />\n </ErrorBoundary>\n <footer>... ๊ธ๋ก๋ฒ ํธํฐ ...</footer>\n </div>\n );\n}\n
์ด `MainApp` ์์์์ `GlobalDashboard` (๋๋ ๊ทธ ์์์ธ `UserProfile`, `LatestOrders`, `AnalyticsWidget`) ๋ด์ ์ด๋ค ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์คํจํ๋ฉด, ์ต์์ `ErrorBoundary`๊ฐ ์ด๋ฅผ ํฌ์ฐฉํ ๊ฒ์ ๋๋ค. ์ด๋ ์ผ๊ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ์ค๋ฅ ๋ฉ์์ง์ ์ก์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด ํจํด์ ์คํจ๊ฐ ์ ์ฒด ๋ทฐ๋ฅผ ๋ฌด์๋ฏธํ๊ฒ ๋ง๋ค ์ ์๋ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ์น์ ์ ํนํ ์ค์ํ๋ฉฐ, ์ฌ์ฉ์์๊ฒ ์ ์ฒด ์น์ ์ ์๋ก๊ณ ์นจํ๊ฑฐ๋ ์๋ ค์ง ์ ์ ์ํ๋ก ๋์๊ฐ๋๋ก ์ ๋ํฉ๋๋ค.
์๋๋ฆฌ์ค 3: ์ ์ธ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ํน์ ํ์ฒ/๋ฆฌ์์ค ์คํจ
`createResource` ์ ํธ๋ฆฌํฐ๋ ์์์ผ ๋ฟ์ด์ง๋ง, ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฐ๋ฐ์๋ค์ React Query, SWR ๋๋ Apollo Client์ ๊ฐ์ ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ํ์นญ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์บ์ฑ, ์ฌ๊ฒ์ฆ, Suspense์์ ํตํฉ์ ์ํ ๋ด์ฅ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ๋ฉฐ, ์ค์ํ๊ฒ๋ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์๋ฅผ ๋ค์ด, React Query๋ ๋ก๋ฉ ์ ์ค๋จ๋๋๋ก ๊ตฌ์ฑํ ์ ์๋ `useQuery` ํ ์ ์ ๊ณตํ๋ฉฐ, `isError` ๋ฐ `error` ์ํ๋ ์ ๊ณตํฉ๋๋ค. `suspense: true`๊ฐ ์ค์ ๋๋ฉด `useQuery`๋ ๋ณด๋ฅ ์ํ์ ๋ํด ํ๋ผ๋ฏธ์ค๋ฅผ ๋์ง๊ณ ๊ฑฐ๋ถ ์ํ์ ๋ํด ์ค๋ฅ๋ฅผ ๋์ง๋ฏ๋ก Suspense ๋ฐ Error Boundaries์ ์๋ฒฝํ๊ฒ ํธํ๋ฉ๋๋ค.
์ด๊ฒ์ "React Query๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ ํ์นญ (๊ฐ๋ ์ )"์ ์์์ ๋๋ค:
import { useQuery } from 'react-query';\n\nconst fetchUserProfile = async (userId) => {\n const response = await fetch(`/api/users/${userId}`);\n if (!response.ok) {\n throw new Error(`Failed to fetch user ${userId} data: ${response.statusText}`);\n }\n return response.json();\n};\n\nconst UserProfile = ({ userId }) => {\n const { data: user } = useQuery(['user', userId], () => fetchUserProfile(userId), {\n suspense: true, // Enable Suspense integration\n // Potentially, some error handling here could also be managed by React Query itself\n // For example, retries: 3,\n // onError: (error) => console.error("Query error:", error)\n });\n\n return (\n <div>\n <h3>์ฌ์ฉ์ ํ๋กํ: {user.name}</h3>\n <p>์ด๋ฉ์ผ: {user.email}</p>\n </div>\n );\n};\n\n// Then, wrap UserProfile in Suspense and ErrorBoundary as before\n// <ErrorBoundary>\n// <Suspense fallback={<p>์ฌ์ฉ์ ํ๋กํ ๋ก๋ ์ค...</p>}>\n// <UserProfile userId={123} />\n// </Suspense>\n// </ErrorBoundary>\n
Suspense ํจํด์ ์์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด Error Boundaries๋ฅผ ํตํ ์ค๋ฅ ๋ณต๊ตฌ๋ฟ๋ง ์๋๋ผ ์๋ ์ฌ์๋, ์บ์ฑ, ๋ฐ์ดํฐ ์ต์ ์ํ ๊ด๋ฆฌ์ ๊ฐ์ ๊ธฐ๋ฅ๋ ์ป์ ์ ์์ต๋๋ค. ์ด๋ ๋ค์ํ ๋คํธ์ํฌ ํ๊ฒฝ์ ์ง๋ฉดํ ๊ธ๋ก๋ฒ ์ฌ์ฉ์์๊ฒ ์ฑ๋ฅ ์ข๊ณ ์ ๋ขฐํ ์ ์๋ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
์ค๋ฅ์ ๋ํ ํจ๊ณผ์ ์ธ ํด๋ฐฑ UI ์ค๊ณ
๊ธฐ๋ฅ์ ์ธ ์ค๋ฅ ๋ณต๊ตฌ ์์คํ ์ ์ ๋ฐ์ ์ธ์์ผ ๋ฟ์ ๋๋ค. ๋๋จธ์ง ์ ๋ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ฌ์ฉ์์ ํจ๊ณผ์ ์ผ๋ก ์ํตํ๋ ๊ฒ์ ๋๋ค. ์ ์ค๊ณ๋ ์ค๋ฅ ํด๋ฐฑ UI๋ ์ ์ฌ์ ์ผ๋ก ์ข์ ์ค๋ฌ์ด ๊ฒฝํ์ ๊ด๋ฆฌ ๊ฐ๋ฅํ ๊ฒฝํ์ผ๋ก ๋ฐ๊พธ์ด ์ฌ์ฉ์ ์ ๋ขฐ๋ฅผ ์ ์งํ๊ณ ํด๊ฒฐ์ฑ ์ผ๋ก ์๋ดํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ๊ฒฝํ ๊ณ ๋ ค ์ฌํญ
- ๋ช ํ์ฑ๊ณผ ๊ฐ๊ฒฐ์ฑ: ์ค๋ฅ ๋ฉ์์ง๋ ๊ธฐ์ ์ฉ์ด๋ฅผ ํผํ๊ณ ์ดํดํ๊ธฐ ์ฌ์์ผ ํฉ๋๋ค. "์ ํ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ์ง ๋ชปํ์ต๋๋ค"๊ฐ "TypeError: Cannot read property 'name' of undefined"๋ณด๋ค ๋ซ์ต๋๋ค.
- ์คํ ๊ฐ๋ฅ์ฑ: ๊ฐ๋ฅํ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ทจํ ์ ์๋ ๋ช ํํ ์กฐ์น๋ฅผ ์ ๊ณตํ์ญ์์ค. ์ด๋ "์ฌ์๋" ๋ฒํผ, "ํ์ผ๋ก ๋์๊ฐ๊ธฐ" ๋งํฌ ๋๋ "๊ณ ๊ฐ ์ง์ํ์ ๋ฌธ์" ์ง์นจ์ผ ์ ์์ต๋๋ค.
- ๊ณต๊ฐ: ์ฌ์ฉ์์ ์ข์ ๊ฐ์ ์ธ์ ํ์ญ์์ค. "๋ถํธ์ ๋๋ ค ์ฃ์กํฉ๋๋ค"์ ๊ฐ์ ๋ฌธ๊ตฌ๋ ํฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์ผ๊ด์ฑ: ์ค๋ฅ ์ํ์์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ธ๋๋ฉ๊ณผ ๋์์ธ ์ธ์ด๋ฅผ ์ ์งํ์ญ์์ค. ๊ฑฐ์ฌ๋ฆฌ๊ณ ์คํ์ผ์ด ์ ์ฉ๋์ง ์์ ์ค๋ฅ ํ์ด์ง๋ ๊นจ์ง ํ์ด์ง๋งํผ ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
- ๋งฅ๋ฝ: ์ค๋ฅ๊ฐ ์ ์ญ์ ์ธ๊ฐ์, ์๋๋ฉด ๋ก์ปฌ์ ์ธ๊ฐ์? ์ปดํฌ๋ํธ๋ณ ์ค๋ฅ๋ ์ฑ ์ ์ฒด์ ์น๋ช ์ ์ธ ์คํจ๋ณด๋ค ๋ ๋ฐฉํด์ ์ด์ด์ผ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ๋ฐ ๋ค๊ตญ์ด ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ค์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ค๊ณํ๋ ๊ฒ์ ์ถ๊ฐ์ ์ธ ๊ณ ๋ ค๊ฐ ํ์ํฉ๋๋ค:
- ํ์งํ: ๋ชจ๋ ์ค๋ฅ ๋ฉ์์ง๋ ํ์งํ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค. ์ฌ์ฉ์์ ์ ํธ ์ธ์ด๋ก ๋ฉ์์ง๊ฐ ํ์๋๋๋ก ๊ตญ์ ํ(i18n) ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ญ์์ค.
- ๋ฌธํ์ ๋ฏธ๋ฌํจ: ๋ค๋ฅธ ๋ฌธํ๊ถ์์๋ ํน์ ๋ฌธ๊ตฌ๋ ์ด๋ฏธ์ง๋ฅผ ๋ค๋ฅด๊ฒ ํด์ํ ์ ์์ต๋๋ค. ์ค๋ฅ ๋ฉ์์ง์ ํด๋ฐฑ ๊ทธ๋ํฝ์ด ๋ฌธํ์ ์ผ๋ก ์ค๋ฆฝ์ ์ด๊ฑฐ๋ ์ ์ ํ๊ฒ ํ์งํ๋์๋์ง ํ์ธํ์ญ์์ค.
- ์ ๊ทผ์ฑ: ์ค๋ฅ ๋ฉ์์ง๊ฐ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์์๊ฒ๋ ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ๋ณด์ฅํ์ญ์์ค. ARIA ์์ฑ, ๋ช ํํ ๋๋น๋ฅผ ์ฌ์ฉํ๊ณ ํ๋ฉด ํ๋ ๊ธฐ๊ฐ ์ค๋ฅ ์ํ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์๋ฆด ์ ์๋๋ก ํ์ญ์์ค.
- ๋คํธ์ํฌ ๊ฐ๋ณ์ฑ: ์ผ๋ฐ์ ์ธ ๊ธ๋ก๋ฒ ์๋๋ฆฌ์ค์ ๋ง์ถฐ ๋ฉ์์ง๋ฅผ ์กฐ์ ํ์ญ์์ค. ๊ฐ๋ฐ๋์๊ตญ ์ธํ๋ผ๋ฅผ ๊ฐ์ง ์ง์ญ์ ์ฌ์ฉ์์๊ฒ ๋ฐ์ํ ์ ์๋ ์ฃผ์ ์์ธ์ด "๋์ ๋คํธ์ํฌ ์ฐ๊ฒฐ" ๋๋ฌธ์ด๋ผ๋ฉด, ์ผ๋ฐ์ ์ธ "์๋ฒ ์ค๋ฅ"๋ณด๋ค "๋์ ๋คํธ์ํฌ ์ฐ๊ฒฐ"๋ก ์ธํ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ ์ ์ฉํฉ๋๋ค.
์์์ ๋ณธ `ErrorBoundary` ์์๋ฅผ ๊ณ ๋ คํด ๋ณด์ธ์. ์ฐ๋ฆฌ๋ ๊ฐ๋ฐ์๋ฅผ ์ํ `showDetails` prop๊ณผ ์ฌ์ฉ์๋ฅผ ์ํ `onRetry` prop์ ํฌํจํ์ต๋๋ค. ์ด ๋ถ๋ฆฌ๋ฅผ ํตํด ๊ธฐ๋ณธ์ ์ผ๋ก ๊น๋ํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ฉด์๋ ํ์ํ ๋ ๋ ์์ธํ ์ง๋จ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
ํด๋ฐฑ์ ์ ํ
ํด๋ฐฑ UI๋ ๋จ์ํ ์ผ๋ฐ ํ ์คํธ์ผ ํ์๋ ์์ต๋๋ค:
- ๊ฐ๋จํ ํ ์คํธ ๋ฉ์์ง: "๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ์ง ๋ชปํ์ต๋๋ค. ๋ค์ ์๋ํด ์ฃผ์ธ์."
- ๊ทธ๋ฆผ ๋ฉ์์ง: ๋์ด์ง ์ฐ๊ฒฐ, ์๋ฒ ์ค๋ฅ ๋๋ ์๋ ํ์ด์ง๋ฅผ ๋ํ๋ด๋ ์์ด์ฝ ๋๋ ๊ทธ๋ฆผ.
- ๋ถ๋ถ ๋ฐ์ดํฐ ํ์: ์ผ๋ถ ๋ฐ์ดํฐ๋ ๋ก๋๋์์ง๋ง ์ ์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ, ํน์ ์คํจ ์น์ ์ ์ค๋ฅ ๋ฉ์์ง์ ํจ๊ป ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐ์ดํฐ๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
- ์ค๋ฅ ์ค๋ฒ๋ ์ด๊ฐ ์๋ ์ค์ผ๋ ํค UI: ์ค์ผ๋ ํค ๋ก๋ฉ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋, ํน์ ์น์ ๋ด์์ ์ค๋ฅ๋ฅผ ๋ํ๋ด๋ ์ค๋ฒ๋ ์ด์ ํจ๊ป ๋ ์ด์์์ ์ ์งํ๋ฉด์ ๋ฌธ์ ์์ญ์ ๋ช ํํ๊ฒ ๊ฐ์กฐํฉ๋๋ค.
ํด๋ฐฑ์ ์ ํ์ ์ค๋ฅ์ ์ฌ๊ฐ์ฑ๊ณผ ๋ฒ์์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ์์ ์์ ฏ์ด ์คํจํ๋ฉด ๋ฏธ๋ฌํ ๋ฉ์์ง๋ก ์ถฉ๋ถํ ์ ์์ง๋ง, ์ ์ฒด ๋์๋ณด๋์ ์ค์ํ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์คํจ๋ ๋ช ํํ ์ง์นจ์ด ํฌํจ๋ ๋์ ๋๋ ์ ์ฒด ํ๋ฉด ๋ฉ์์ง๊ฐ ํ์ํ ์ ์์ต๋๋ค.
๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ํ ๊ณ ๊ธ ์ ๋ต
๊ธฐ๋ณธ์ ์ธ ํตํฉ์ ๋์ด, ๋ช ๊ฐ์ง ๊ณ ๊ธ ์ ๋ต์ ํนํ ๊ธ๋ก๋ฒ ์ฌ์ฉ์ ๊ธฐ๋ฐ์ ์๋น์ค๋ฅผ ์ ๊ณตํ ๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋ ฅ์ฑ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ๋์ฑ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์ฌ์๋ ๋ฉ์ปค๋์ฆ
์ผ์์ ์ธ ๋คํธ์ํฌ ๋ฌธ์ ๋๋ ์์ ์๋ฒ ์ค๋ฅ๋ ํํ ๋ฐ์ํ๋ฉฐ, ํนํ ์๋ฒ์์ ์ง๋ฆฌ์ ์ผ๋ก ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๊ฑฐ๋ ๋ชจ๋ฐ์ผ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์์๊ฒ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. ๋ฐ๋ผ์ ์ฌ์๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ์๋ ์ฌ์๋ ๋ฒํผ: `ErrorBoundary` ์์์์ ๋ณธ ๊ฒ์ฒ๋ผ, ๊ฐ๋จํ ๋ฒํผ์ผ๋ก ์ฌ์ฉ์๊ฐ ๋ค์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์์ํ ์ ์์ต๋๋ค. ์ด๋ ์ฌ์ฉ์์๊ฒ ๊ถํ์ ๋ถ์ฌํ๊ณ ๋ฌธ์ ๊ฐ ์ผ์์ ์ผ ์ ์์์ ์ธ์ ํ๋ ๊ฒ์ ๋๋ค.
- ์ง์ ๋ฐฑ์คํ๋ฅผ ์ฌ์ฉํ ์๋ ์ฌ์๋: ์ค์ํ์ง ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฐ์ ธ์ค๊ธฐ์ ๊ฒฝ์ฐ, ์๋ ์ฌ์๋๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. React Query ๋ฐ SWR๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํฉ๋๋ค. ์ง์ ๋ฐฑ์คํ๋ ๋ณต๊ตฌ ์ค์ธ ์๋ฒ๋ ๋ถ์์ ํ ๋คํธ์ํฌ๋ฅผ ๊ณผ๋ถํ์ํค์ง ์๊ธฐ ์ํด ์ฌ์๋ ์๋ ๊ฐ์ ์ ์ ๋ ๊ธด ์๊ฐ(์: 1์ด, 2์ด, 4์ด, 8์ด)์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ด๋ ํธ๋ํฝ์ด ๋ง์ ๊ธ๋ก๋ฒ API์ ํนํ ์ค์ํฉ๋๋ค.
- ์กฐ๊ฑด๋ถ ์ฌ์๋: ํน์ ์ ํ์ ์ค๋ฅ(์: ๋คํธ์ํฌ ์ค๋ฅ, 5xx ์๋ฒ ์ค๋ฅ)๋ง ์ฌ์๋ํ๊ณ ํด๋ผ์ด์ธํธ ์ธก ์ค๋ฅ(์: 4xx, ์๋ชป๋ ์ ๋ ฅ)๋ ์ฌ์๋ํ์ง ์์ต๋๋ค.
- ๊ธ๋ก๋ฒ ์ฌ์๋ ์ปจํ ์คํธ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด ๋ฌธ์ ์ ๊ฒฝ์ฐ, React Context๋ฅผ ํตํด ์ ๊ณต๋๋ ๊ธ๋ก๋ฒ ์ฌ์๋ ํจ์๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ด๋ ์ฑ์ ์ด๋ ๊ณณ์์๋ ์ค์ํ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ค์ ์ด๊ธฐํํ๊ธฐ ์ํด ํธ๋ฆฌ๊ฑฐ๋ ์ ์์ต๋๋ค.
๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง
์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์ฌ์ฉ์์๊ฒ ์ข์ง๋ง, ์ค๋ฅ๊ฐ *์* ๋ฐ์ํ๋์ง ์ดํดํ๋ ๊ฒ์ ๊ฐ๋ฐ์์๊ฒ ๋งค์ฐ ์ค์ํฉ๋๋ค. ํนํ ๋ถ์ฐ ์์คํ ๋ฐ ๋ค์ํ ์ด์ ํ๊ฒฝ์์ ๋ฌธ์ ๋ฅผ ์ง๋จํ๊ณ ํด๊ฒฐํ๋ ๋ฐ ๊ฒฌ๊ณ ํ ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง์ด ํ์์ ์ ๋๋ค.
- ํด๋ผ์ด์ธํธ ์ธก ๋ก๊น : ๊ฐ๋ฐ์ฉ์ผ๋ก๋ `console.error`๋ฅผ ์ฌ์ฉํ์ง๋ง, ํ๋ก๋์ ์ฉ์ผ๋ก๋ Sentry, LogRocket์ ๊ฐ์ ์ ์ฉ ์ค๋ฅ ๋ณด๊ณ ์๋น์ค ๋๋ ์ฌ์ฉ์ ์ง์ ๋ฐฑ์๋ ๋ก๊น ์๋ฃจ์ ๊ณผ ํตํฉํ์ญ์์ค. ์ด๋ฌํ ์๋น์ค๋ ์์ธํ ์คํ ์ถ์ , ์ปดํฌ๋ํธ ์ ๋ณด, ์ฌ์ฉ์ ์ปจํ ์คํธ ๋ฐ ๋ธ๋ผ์ฐ์ ๋ฐ์ดํฐ๋ฅผ ์บก์ฒํฉ๋๋ค.
- ์ฌ์ฉ์ ํผ๋๋ฐฑ ๋ฃจํ: ์๋ํ๋ ๋ก๊น ์ธ์๋, ์ฌ์ฉ์๊ฐ ์ค๋ฅ ํ๋ฉด์์ ์ง์ ๋ฌธ์ ๋ฅผ ๋ณด๊ณ ํ ์ ์๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ญ์์ค. ์ด ์ ์ฑ์ ๋ฐ์ดํฐ๋ ์ค์ ์ํฅ์ ์ดํดํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง: ์ค๋ฅ ๋ฐ์ ๋น๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ์ถ์ ํ์ญ์์ค. ์ค๋ฅ์จ์ ๊ธ์ฆ์ ์์คํ ์ ์ธ ๋ฌธ์ ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ๋ชจ๋ํฐ๋ง์ ์ค๋ฅ์ ์ง๋ฆฌ์ ๋ถํฌ๋ฅผ ์ดํดํ๋ ๊ฒ๋ ํฌํจํฉ๋๋ค. ์ค๋ฅ๊ฐ ํน์ ์ง์ญ์ ์ง์ค๋์ด ์์ต๋๊น? ์ด๋ CDN ๋ฌธ์ , ์ง์ญ๋ณ API ์ค๋จ ๋๋ ํด๋น ์ง์ญ์ ๊ณ ์ ํ ๋คํธ์ํฌ ๋ฌธ์ ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
์ฌ์ ๋ก๋ฉ ๋ฐ ์บ์ฑ ์ ๋ต
๊ฐ์ฅ ์ข์ ์ค๋ฅ๋ ๊ฒฐ์ฝ ๋ฐ์ํ์ง ์๋ ์ค๋ฅ์ ๋๋ค. ์ฌ์ ์๋ฐฉ์ ์ ๋ต์ ๋ก๋ฉ ์คํจ ๋ฐ์๋ฅ ์ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์ฌ์ ๋ก๋ฉ: ๋ค์ ํ์ด์ง๋ ์ํธ์์ฉ์์ ํ์ํ ์ค์ํ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ํ์ฌ ํ์ด์ง์ ์๋ ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฏธ๋ฆฌ ๋ก๋ํ์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ค์ ์ํ๋ก์ ์ ํ์ด ์ฆ๊ฐ์ ์ผ๋ก ๋๊ปด์ง๊ณ ์ด๊ธฐ ๋ก๋ฉ ์ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ญ๋๋ค.
- ์บ์ฑ(Stale-While-Revalidate): ์ ๊ทน์ ์ธ ์บ์ฑ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ์ญ์์ค. React Query ๋ฐ SWR๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์บ์์์ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ์ ๊ณตํ๋ ๋์์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ ํจ์ฑ์ ๋ค์ ๊ฒ์ฌํจ์ผ๋ก์จ ์ด ๋ถ์ผ์์ ํ์ํฉ๋๋ค. ์ ํจ์ฑ ์ฌ๊ฒ์ฌ๊ฐ ์คํจํ๋๋ผ๋ ์ฌ์ฉ์๋ ๋น ํ๋ฉด์ด๋ ์ค๋ฅ ๋์ ๊ด๋ จ์ฑ ์๋(๋น๋ก ์ ์ฌ์ ์ผ๋ก ์ค๋๋) ์ ๋ณด๋ฅผ ๊ณ์ ๋ณด๊ฒ ๋ฉ๋๋ค. ์ด๋ ๋๋ฆฌ๊ฑฐ๋ ๊ฐํ์ ์ธ ๋คํธ์ํฌ ์ฌ์ฉ์์๊ฒ ํ๋๋ฅผ ๋ฐ๊พธ๋ ์์์ ๋๋ค.
- ์คํ๋ผ์ธ ์ฐ์ ์ ๊ทผ ๋ฐฉ์: ์คํ๋ผ์ธ ์ก์ธ์ค๊ฐ ์ฐ์ ์๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ์ค์ํ ๋ฐ์ดํฐ๋ฅผ ๋ก์ปฌ์ ์ ์ฅํ๊ธฐ ์ํด PWA(Progressive Web App) ๊ธฐ์ ๋ฐ IndexedDB๋ฅผ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ๋คํธ์ํฌ ์คํจ์ ๋ํ ๊ทน๋จ์ ์ธ ํํ์ ํ๋ ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.
์ค๋ฅ ๊ด๋ฆฌ ๋ฐ ์ํ ์ฌ์ค์ ์ ์ํ ์ปจํ ์คํธ
๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ค๋ฅ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ฌ์ค์ ์ ํธ๋ฆฌ๊ฑฐํ๋ ๋ณด๋ค ์ค์ ์ง์คํ๋ ๋ฐฉ๋ฒ์ด ํ์ํ ์ ์์ต๋๋ค. React Context๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ปดํฌ๋ํธ๊ฐ ์ค๋ฅ๋ฅผ ์๋ฆฌ๊ฑฐ๋ ์ค๋ฅ ๊ด๋ จ ๊ธฐ๋ฅ(๊ธ๋ก๋ฒ ์ฌ์๋ ํจ์ ๋๋ ์ค๋ฅ ์ํ๋ฅผ ์ง์ฐ๋ ๋ฉ์ปค๋์ฆ ๋ฑ)์ ์ ๊ทผํ ์ ์๋๋ก `ErrorContext`๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, Error Boundary๋ ์ปจํ ์คํธ๋ฅผ ํตํด `resetError` ํจ์๋ฅผ ๋ ธ์ถํ์ฌ ์์ ์ปดํฌ๋ํธ(์: ์ค๋ฅ ํด๋ฐฑ UI์ ํน์ ๋ฒํผ)๊ฐ ํน์ ์ปดํฌ๋ํธ ์ํ ์ฌ์ค์ ๊ณผ ํจ๊ป ๋ค์ ๋ ๋๋ง ๋ฐ ๋ค์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ํธ๋ฆฌ๊ฑฐํ ์ ์๋๋ก ํ ์ ์์ต๋๋ค.
ํํ ํจ์ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก
Suspense์ Error Boundaries๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ํ๋ ค๋ฉด ์ ์คํ ๊ณ ๋ ค๊ฐ ํ์ํฉ๋๋ค. ๋ค์์ ํ๋ ฅ์ ์ธ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด ํผํด์ผ ํ ์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ์ฑํํด์ผ ํ ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค.
ํํ ํจ์
- Error Boundary ๋๋ฝ: ๊ฐ์ฅ ํํ ์ค์์ ๋๋ค. Error Boundary๊ฐ ์์ผ๋ฉด Suspense๊ฐ ํ์ฑํ๋ ์ปดํฌ๋ํธ์์ ๊ฑฐ๋ถ๋ ํ๋ผ๋ฏธ์ค๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ถฉ๋์์ผ ์ฌ์ฉ์์๊ฒ ๋น ํ๋ฉด์ ๋จ๊ธธ ๊ฒ์ ๋๋ค.
- ์ผ๋ฐ์ ์ธ ์ค๋ฅ ๋ฉ์์ง: "์์์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค"๋ ๊ฑฐ์ ๊ฐ์น๊ฐ ์์ต๋๋ค. ํนํ ๋ค์ํ ์ ํ์ ์คํจ(๋คํธ์ํฌ, ์๋ฒ, ๋ฐ์ดํฐ ์์)์ ๋ํด ๊ตฌ์ฒด์ ์ด๊ณ ์คํ ๊ฐ๋ฅํ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ค๊ณ ๋ ธ๋ ฅํ์ญ์์ค.
- ๊ณผ๋ํ Error Boundary ์ค์ฒฉ: ์ธ๋ฐํ ์ค๋ฅ ์ ์ด๊ฐ ์ข์ง๋ง, ๋ชจ๋ ์์ ์ปดํฌ๋ํธ๋ง๋ค Error Boundary๋ฅผ ๊ฐ์ง๋ ๊ฒ์ ์ค๋ฒํค๋์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๋ฅผ ๋ ผ๋ฆฌ์ ๋จ์(์: ์น์ , ์์ ฏ)๋ก ๊ทธ๋ฃนํํ๊ณ ํด๋น ๋จ์๋ค์ ๋ํํ์ญ์์ค.
- ๋ก๋ฉ๊ณผ ์ค๋ฅ๋ฅผ ๊ตฌ๋ถํ์ง ์์: ์ฌ์ฉ์๋ ์ฑ์ด ์ฌ์ ํ ๋ก๋ํ๋ ค๊ณ ์๋ํ๋์ง ์๋๋ฉด ํ์คํ ์คํจํ๋์ง ์์์ผ ํฉ๋๋ค. ๊ฐ ์ํ์ ๋ํ ๋ช ํํ ์๊ฐ์ ๋จ์์ ๋ฉ์์ง๊ฐ ์ค์ํฉ๋๋ค.
- ์๋ฒฝํ ๋คํธ์ํฌ ์กฐ๊ฑด ๊ฐ์ : ์ ์ธ๊ณ์ ์ผ๋ก ๋ง์ ์ฌ์ฉ์๊ฐ ์ ํ๋ ๋์ญํญ, ์ข ๋์ ์ฐ๊ฒฐ ๋๋ ๋ถ์์ ํ Wi-Fi์์ ์๋ํ๋ค๋ ์ฌ์ค์ ์์ผ๋ฉด ์ทจ์ฝํ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค.
- ์ค๋ฅ ์ํ๋ฅผ ํ ์คํธํ์ง ์์: ๊ฐ๋ฐ์๋ค์ ์ข ์ข ํ๋ณต ๊ฒฝ๋ก๋ฅผ ํ ์คํธํ์ง๋ง, ๋คํธ์ํฌ ์คํจ(์: ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ ๋๊ตฌ ์ฌ์ฉ), ์๋ฒ ์ค๋ฅ ๋๋ ์๋ชป๋ ํ์์ ๋ฐ์ดํฐ ์๋ต์ ์๋ฎฌ๋ ์ด์ ํ๋ ๊ฒ์ ์ํํ ํฉ๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก
- ๋ช ํํ ์ค๋ฅ ๋ฒ์ ์ ์: ์ค๋ฅ๊ฐ ๋จ์ผ ์ปดํฌ๋ํธ, ์น์ ๋๋ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํฅ์ ๋ฏธ์ณ์ผ ํ๋์ง ๊ฒฐ์ ํ์ญ์์ค. ์ด๋ฌํ ๋ ผ๋ฆฌ์ ๊ฒฝ๊ณ์ Error Boundary๋ฅผ ์ ๋ต์ ์ผ๋ก ๋ฐฐ์นํ์ญ์์ค.
- ์คํ ๊ฐ๋ฅํ ํผ๋๋ฐฑ ์ ๊ณต: ํญ์ ์ฌ์ฉ์์๊ฒ ์ต์ ์ ์ ๊ณตํ์ญ์์ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ์์ ๋ณด๊ณ ํ๊ฑฐ๋ ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ๋ ๊ฒ์ผ์ง๋ผ๋ ๋ง์ ๋๋ค.
- ์ค๋ฅ ๋ก๊น ์ค์ ์ง์คํ: ๊ฐ๋ ฅํ ์ค๋ฅ ๋ชจ๋ํฐ๋ง ์๋น์ค์ ํตํฉํ์ญ์์ค. ์ด๋ ์ ์ธ๊ณ ์ฌ์ฉ์ ๊ธฐ๋ฐ์์ ์ค๋ฅ๋ฅผ ์ถ์ , ๋ถ๋ฅ ๋ฐ ์ฐ์ ์์๋ฅผ ์ง์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
- ํ๋ ฅ์ฑ์ ์ํ ์ค๊ณ: ์คํจ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ์ญ์์ค. Error Boundary๊ฐ ์ฌ๊ฐํ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ ์๋ ๋๋ฝ๋ ๋ฐ์ดํฐ๋ ์์์น ๋ชปํ ํ์์ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๋๋ก ์ปดํฌ๋ํธ๋ฅผ ์ค๊ณํ์ญ์์ค.
- ํ ๊ต์ก: ํ์ ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ Suspense, ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ Error Boundaries ๊ฐ์ ์ํธ ์์ฉ์ ์ดํดํ๋๋ก ํ์ญ์์ค. ์ ๊ทผ ๋ฐฉ์์ ์ผ๊ด์ฑ์ ๊ณ ๋ฆฝ๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
- ์ฒซ๋ ๋ถํฐ ๊ธ๋ก๋ฒํ๊ฒ ์๊ฐํ๊ธฐ: ์ค๊ณ ๋จ๊ณ๋ถํฐ ๋คํธ์ํฌ ๊ฐ๋ณ์ฑ, ๋ฉ์์ง ํ์งํ ๋ฐ ์ค๋ฅ ๊ฒฝํ์ ๋ํ ๋ฌธํ์ ๋งฅ๋ฝ์ ๊ณ ๋ คํ์ญ์์ค. ํ ๊ตญ๊ฐ์์๋ ๋ช ํํ ๋ฉ์์ง๊ฐ ๋ค๋ฅธ ๊ตญ๊ฐ์์๋ ๋ชจํธํ๊ฑฐ๋ ์ฌ์ง์ด ๋ถ์พํ ์ ์์ต๋๋ค.
- ์ค๋ฅ ๊ฒฝ๋ก ํ ์คํธ ์๋ํ: ๋คํธ์ํฌ ์คํจ, API ์ค๋ฅ ๋ฐ ๊ธฐํ ๋ถ๋ฆฌํ ์กฐ๊ฑด์ ํน๋ณํ ์๋ฎฌ๋ ์ด์ ํ๋ ํ ์คํธ๋ฅผ ํตํฉํ์ฌ ์ค๋ฅ ๊ฒฝ๊ณ ๋ฐ ํด๋ฐฑ์ด ์์๋๋ก ์๋ํ๋์ง ํ์ธํ์ญ์์ค.
Suspense ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ์ ๋ฏธ๋
Suspense๋ฅผ ํฌํจํ React์ ๋์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ ํ ์งํ ์ค์ ๋๋ค. ๋์ ๋ชจ๋๊ฐ ์์ ํ๋๊ณ ๊ธฐ๋ณธ๊ฐ์ด ๋จ์ ๋ฐ๋ผ, ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ ๊ณ์ํด์ ๊ฐ์ ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ์ ์ํด ๋ ๋๋ง์ ์ค๋จํ๊ณ ์ฌ๊ฐํ๋ React์ ๋ฅ๋ ฅ์ ์คํจํ ์์ ์ ์ฌ์๋ํ๊ฑฐ๋ ๋ฌธ์ ๊ฐ ์๋ ์น์ ์์ ๋ฒ์ด๋ ๋ ํจ์ฌ ๋ ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
React ํ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ฐ์ดํฐ ํ์นญ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ถ๊ฐ์ ์ธ ๋ด์ฅ ์ถ์ํ๊ฐ ๋ฑ์ฅํ์ฌ ์ฌ๊ธฐ์ ๋ ผ์๋ ์ผ๋ถ ํจํด์ ์ ์ฌ์ ์ผ๋ก ๋จ์ํํ ์ ์๋ค๊ณ ์ธ๊ธํ์ต๋๋ค. ๊ทธ๋ฌ๋ Suspense๊ฐ ํ์ฑํ๋ ์์ ์์ ๊ฑฐ๋ถ(rejections)๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ํด Error Boundaries๋ฅผ ์ฌ์ฉํ๋ ๊ทผ๋ณธ์ ์ธ ์์น์ ๊ฒฌ๊ณ ํ React ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ์ด์์ผ๋ก ๋จ์์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
์ปค๋ฎค๋ํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ํ ๊ณ์ ํ์ ํ์ฌ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ฐ ์ ์ฌ์ ์คํจ์ ๋ณต์ก์ฑ์ ๊ด๋ฆฌํ๋ ๋์ฑ ์ ๊ตํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ๊ฐ๋ฐ ๋ํฅ์ ๊ณ์ ์ฃผ์ํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ณ ๋๋ก ํ๋ ฅ์ ์ด๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋๋ ์ต์ ๊ธฐ์ ์ ํ์ฉํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
React Suspense๋ ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์ฐ์ํ ์๋ฃจ์ ์ ์ ๊ณตํ๋ฉฐ, ์ ๋์ ์ด๊ณ ๋ฐ์์ ์ธ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ์๋ก์ด ์๋๋ฅผ ์ด๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๋ ๊ทธ ํ์ ํฌ๊ด์ ์ธ ์ค๋ฅ ๋ณต๊ตฌ ์ ๋ต๊ณผ ๊ฒฐํฉ๋ ๋์๋ง ์์ ํ ์คํ๋ฉ๋๋ค. React Error Boundaries๋ ๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ ๋ฐ ๊ธฐํ ์์์น ๋ชปํ ๋ฐํ์ ์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๋ ๋ฐ ํ์ํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ๋ ์๋ฒฝํ ๋ณด์์ฌ์ ๋๋ค.
Suspense์ Error Boundaries๊ฐ ์ด๋ป๊ฒ ํจ๊ป ์๋ํ๋์ง ์ดํดํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ํ ์์ค์์ ์ ์คํ๊ฒ ๊ตฌํํจ์ผ๋ก์จ ๋๋๋๋ก ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๊ณต๊ฐ์ ์ด๊ณ ์คํ ๊ฐ๋ฅํ๋ฉฐ ํ์งํ๋ ํด๋ฐฑ UI๋ฅผ ์ค๊ณํ๋ ๊ฒ ๋ํ ๋๊ฐ์ด ์ค์ํ๋ฉฐ, ์ฌ์ฉ์๋ค์ด ์์น๋ ๋คํธ์ํฌ ์กฐ๊ฑด์ ๊ด๊ณ์์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ํผ๋์ค๋ฌ์ํ๊ฑฐ๋ ์ข์ ํ์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
Error Boundaries์ ์ ๋ต์ ๋ฐฐ์น๋ถํฐ ๊ณ ๊ธ ์ฌ์๋ ๋ฐ ๋ก๊น ๋ฉ์ปค๋์ฆ์ ์ด๋ฅด๊ธฐ๊น์ง ์ด๋ฌํ ํจํด์ ์์ฉํ๋ฉด ์์ ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ด๋ฉฐ ์ ์ธ๊ณ์ ์ผ๋ก ๊ฒฌ๊ณ ํ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ํธ ์ฐ๊ฒฐ๋ ๋์งํธ ๊ฒฝํ์ ์ ์ ๋ ์์กดํ๋ ์ธ์์์ React Suspense ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ ๋จ์ํ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ์๋๋๋ค. ๊ทธ๊ฒ์ ์๊ฐ๊ณผ ์์์น ๋ชปํ ๋์ ์ ๊ฒฌ๋๋ด๋ ๊ณ ํ์ง์ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ทผ๋ณธ์ ์ธ ์๊ตฌ ์ฌํญ์ ๋๋ค.